module Pages.Summary
     ( summaryPage, problemsServiceHandler
     ) where

import qualified Data.Map as Map (elems)

import Happstack.Server  (setHeaderM,
        ToMessage(..), Method(GET, OPTIONS), Response, ServerPart,
        methodM, methodSP, toResponse)
import Happstack.State   (query)
import State.Database

import Control.Monad(forM_, msum)

import State.TuuraQueries (ReadTuuraDb(..))
import Pages.ProblemSummary
import Pages.SubmissionSummary

import Controllers.WebService

import Pages.MasterPage(masterPage)

import Text.Blaze.Html5
import Text.Blaze.Renderer.Pretty

import Data.ByteString.Lazy.UTF8(fromString)

import Session(readSession)

-- | An Html-wrapper with an instance of ToMessage implementing pretty printing
newtype PrettyHtml = PrettyHtml Html
instance ToMessage PrettyHtml where
    toMessage (PrettyHtml html) = fromString $ renderHtml html
    toContentType (PrettyHtml html) = toContentType html

setGoodHeaders :: ServerPart ()
setGoodHeaders = forM_ [("Access-Control-Allow-Origin", "*"),
                        ("Access-Control-Allow-Credentials", "true"),
                        ("Access-Control-Allow-Methods", "OPTIONS, GET, POST"),
                        ("Access-Control-Allow-Headers", "Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control")]
                        $ \(h,v) -> setHeaderM h v

respondToOptions :: ServerPart Response
respondToOptions = methodSP OPTIONS $ return $ toResponse ()

problemsServiceHandler :: ServerPart Response
problemsServiceHandler = do
       setGoodHeaders
       msum
           [ respondToOptions
           , do
                 methodM GET
                 db  <- query ReadTuuraDb
                 return $ problemsService $ Map.elems (problems db)
           ]

-- | The HTTP handler for the 'Summary' page
summaryPage :: ServerPart Response
summaryPage =
    do methodM GET
       db  <- query ReadTuuraDb
       session <- readSession
       let response = toResponse $ PrettyHtml $ masterPage session "Problem summary page" $ do
            problemSummary $ Map.elems (problems db)
            submissionSummary $ Map.elems (submissions db)
       return response
